package bitcat.chuenyee.utils

import cn.hutool.json.JSON
import cn.hutool.json.JSONUtil
import java.lang.reflect.Field

object BeanCompareUtil {

    /**
     * 将对象转换为可比较的值
     */
    private fun Any?.toComparableValue(): Any? = when (this) {
        is JSON -> this.toString() // 直接转字符串即可，避免 jOOQ 依赖
        else -> this
    }

    /**
     * 比较两个对象指定字段是否相等
     * @param old 老对象
     * @param new 新对象
     * @param fields 要比较的字段名列表
     * @return true 表示所有字段都相等，false 表示至少有一个字段不等
     */
    fun equalsByFields(old: Any, new: Any, fields: List<String>): Boolean {
        fields.forEach { fieldName ->
            val oldFieldValue = getFieldValueSafe(old, fieldName)
            val newFieldValue = getFieldValueSafe(new, fieldName)
            if (oldFieldValue != newFieldValue) return false
        }
        return true
    }

    /**
     * 比较两个列表中对象指定字段是否发生变化
     * @param oldList 老对象列表
     * @param newList 新对象列表
     * @param fields 要比较的字段名列表
     */
    fun listChanged(oldList: List<Any>, newList: List<Any>, fields: List<String>): Boolean {
        if (oldList.size != newList.size) return true
        return oldList.zip(newList).any { (o, n) -> !equalsByFields(o, n, fields) }
    }

    /**
     * 获取对象字段值，如果字段不存在返回 null
     */
    private fun getFieldValueSafe(obj: Any, fieldName: String): Any? {
        return try {
            val field: Field? = obj::class.java.declaredFields.firstOrNull { it.name == fieldName }
            field?.apply { isAccessible = true }?.get(obj)?.toComparableValue()
        } catch (e: Exception) {
            null
        }
    }
}
